﻿using System;
using System.Collections.Generic;
using Dict.DataModel;
using Dict.Config;

namespace Battle.Engine.LogicModel
{
    public class Buff : Engine.Interface.IClientData<ProtoBuf.Message.Buffer> {
        TableBuff buffData = null;
        public string uniqueId;
        public string id; //buff id
        public string group; //buff group
        public string name; //buff name
        public BuffClass buffClass;
        public bool isDebuff; //true为负面buff
        public bool shouldCover; //相同的group只能留val最大的一个
        public bool canBeCleared; //能否被清除buff清除


        public double totalTime; //持续时间
        public int totalRound; //持续回合

        // public int spaceRound; //回合间隔  间隔回合需求未定暂时不做处理
        public int totalCount; //同个buff的次数累加限制

        public int attCount; //攻击生效次数
        public int defCount; //防御生效次数

        public bool onceData;

        public string factor; //buff因子

        public double args1;
        public double args2;
        public double args3;
        public string param;
        
        public IBuffOrigin buffOrigion;            // BUFF来源
        public FActor buffTargetActor;            // BUFF挂载对象

        public double loadBuffTime; //buff加载的时间，也是生效的时间
        public int loadBuffRound; //buff加载的回合，也是生效的回合
        public TalentBuffTriggerTimer timer;

        protected EngineData engineData;


        public string type = "";
        public double val = 0;
        public double val2 = 0;


        public virtual Buff Clone()
        {
            Buff newBuff = this.MemberwiseClone() as Buff;
            newBuff.uniqueId = engineData.uidUtil.GetNewUID("buff");
            newBuff.buffOrigion = null;
            newBuff.buffTargetActor = null;
            return newBuff;
        }

        public virtual void Init(TableBuff tableBuff, EngineData engineData) {
            this.engineData = engineData;
            this.buffData = tableBuff;
            this.id = buffData.Id;
            this.group = buffData.Group;
            this.name = buffData.Name;
            this.buffClass = (BuffClass)tableBuff.BuffClass;
            if (tableBuff.IsDebuff == 1)
            {
                this.isDebuff = true;
            }
            else
            {
                this.isDebuff = false;
            }

            if (tableBuff.ShouldCover == 1)
            {
                this.shouldCover = true;
            }
            else
            {
                this.shouldCover = false;
            }
            if (tableBuff.CanBeCleared == 1)
            {
                this.canBeCleared = true;
            }
            else
            {
                this.canBeCleared = false;
            }

            this.totalTime = tableBuff.TotalTime;
            this.totalRound = tableBuff.TotalRound;
            // this.spaceRound = tableBuff.SpaceRound;
            this.totalCount = tableBuff.TotalCount;
            this.attCount = tableBuff.AttCount;
            this.defCount = tableBuff.DefCount;

            if(this.buffClass == BuffClass.DelayCreate
                || this.totalTime >0 
                || this.totalRound >0 
                || this.attCount >0 
                || this.defCount >0)
            {
                this.onceData = false;
            }
            else
            {//非持续时间 持续回合 攻击次数 防御次数限制的buff，一律标记为一次性buff
                this.onceData = true;
            }
            this.factor = tableBuff.Factor;
            this.type = this.factor;
            this.args1 = tableBuff.Args1;
            this.args2 = tableBuff.Args2;
            this.args3 = tableBuff.Args3;
            this.param = tableBuff.Param;
        }

        public void LoadBuff(FActor target, FSkillCast cast, TalentBuffTriggerTimer timer, FExportOnceData exportOnceData) {
            buffOrigion = new SkillCastBuffOrigin(cast);
            buffTargetActor = target;
            this.loadBuffTime = target.player.engineData.roundTime;
            this.loadBuffRound = target.player.engineData.roundNum;
            this.timer = timer;

            LoadBuff0();
            buffTargetActor.buffManager.LoadBuff(this, timer, exportOnceData);
        }
        
        public void LoadBuff(FActor target, FTalent talent, TalentBuffTriggerTimer timer, FExportOnceData exportOnceData)
        {
            this.buffOrigion = new TalentBuffOrigin(talent);
            this.buffTargetActor = target;
            this.loadBuffTime = target.player.engineData.roundTime;
            this.loadBuffRound = target.player.engineData.roundNum;
            this.timer = timer;

            LoadBuff0();
            this.buffTargetActor.buffManager.LoadBuff(this, timer, exportOnceData);
        }

        public void LoadBuff(FActor target, TalentBuffTriggerTimer timer)
        {
            buffOrigion = null;
            buffTargetActor = target;
            this.loadBuffTime = target.player.engineData.roundTime;
            this.loadBuffRound = target.player.engineData.roundNum;
            this.timer = timer;

            LoadBuff0();
            buffTargetActor.buffManager.LoadBuff(this, timer, null);
        }

        public virtual void LoadBuff0() { }
        public void UnloadBuff() {
            UnloadBuff0();

            buffTargetActor.buffManager.UnLoadBuff(this);
        }
        public virtual void UnloadBuff0() { }

        public virtual void Effect() { }

        public virtual void UnEffect() { }


        public bool Update(EngineData data)
        {
            Update0(data);
            if (this.totalTime > 0)
            {
                if((data.roundTime - this.loadBuffTime) >= this.totalTime)
                {//持续时间buff，在时间到了以后消失
                    UnloadBuff();
                    return true;
                }
            }
            return false;
        }

        public virtual void Update0(EngineData data) { }

        public bool minusRound()
        {
            minusRound0();
            if (this.totalRound > 0)
            {//持续回合buff,在回合到了之后消失
                this.totalRound--;
                if (this.totalRound<=0) {
                    UnloadBuff();
                    return true;
                }
            }
            else if (this.totalTime > 0)
            {//持续时间buff,在回合到了之后清除
                UnloadBuff();
                return true;
            }
            return false;
        }
   
        public virtual void minusRound0() { }

        public bool minusAttCount()
        {
            if (this.attCount > 0)
            {
                this.attCount--;
                if (this.attCount <= 0)
                {
                    UnloadBuff();
                    return true;
                }
            }
            return false;
        }

        public bool minusDefCount()
        {
            if (this.defCount > 0)
            {
                this.defCount--;
                if (this.defCount <= 0)
                {
                    UnloadBuff();
                    return true; 
                }
            }
            return false;
        }

        public ProtoBuf.Message.Buffer DataToClientModel()
        {
            ProtoBuf.Message.Buffer buff = new ProtoBuf.Message.Buffer();
            buff.uid = uniqueId;
            buff.bufferId = id;
            buff.sourceUid = buffOrigion.GetSourceUniqueId();
            buff.targetUid = buffTargetActor.uniqueId;
            return buff;
        }

    }
}
